package erfgame.core.graphics.renderer.chain;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;


import erfgame.core.entity.Entity;
import erfgame.core.graphics.renderer.EntityRenderer;
import erfgame.core.graphics.renderer.PrototypeEntityRenderer;
import erfgame.core.graphics.renderer.RendererUpdateType;
import erfgame.core.util.ColorUtils;
import erfgame.core.world.World;

public class ChainedFillRenderer 
	extends AbstractChainedRenderer 
	implements PrototypeEntityRenderer{
	
	private static final Logger LOG = Logger.getLogger( ChainedFillRenderer.class.getName() );
	
	private BufferedImage fillImage;
	
	private int fillWeight;
	private int originalWeight;
	private int fillColorRGB;
	
	public ChainedFillRenderer(Color fillColor, int fillWeight, int originalWeight) {
		this( fillColor.getRGB() & 0xFFFFFF, fillWeight, originalWeight );
	}

	public ChainedFillRenderer(int rgb, int fillWeight, int originalWeight) {
		this.fillWeight = fillWeight;
		this.fillColorRGB = rgb;
		this.originalWeight = originalWeight;
	}

	
	@Override
	public void setChild(EntityRenderer child, boolean started) {
		super.setChild(child, started);
		if( started && child != null ) {
			rendererUpdated( RendererUpdateType.content, null );
		}
	}


	public BufferedImage createFillImage(EntityRenderer of) {
		Dimension dimension = of.getDimension();
		int width = dimension.width;
		int height = dimension.height;
		BufferedImage fillImage = new BufferedImage( 
				width, 
				height, 
				BufferedImage.TYPE_INT_ARGB 
		);
		Graphics g = fillImage.getGraphics();

		boolean allEmpty = true;
		of.render(g, 0, 0);
		for( int ix=width; ix>0; ) {
			ix--;
			for( int iy=height; iy>0; ) {
				iy--;
				int px = fillImage.getRGB(ix, iy);
				int opacity = (px & 0xFF000000); 
				if( opacity != 0 ) {
					px = ColorUtils.averageColors(px & 0x00FFFFFF, originalWeight, fillColorRGB, fillWeight ) | opacity;
					fillImage.setRGB(ix, iy, px);
					allEmpty = false;
				}
			}
		}
		if( allEmpty ) {
			LOG.log( Level.WARNING, "filled completely empty image, this is suspicious" );
		}
		return fillImage;
	}

	public void render(Graphics g, int x, int y) {
		g.drawImage(this.fillImage, x, y, null);
	}
	
	public void rendererUpdated( RendererUpdateType type, Object state ) {
		this.fillImage = createFillImage(child);	
		super.rendererUpdated(type, state);
	}


	public ChainedFillRenderer spawn(World world, Entity entity) {
		ChainedFillRenderer result;
		result = new ChainedFillRenderer(
				this.fillColorRGB,
				this.fillWeight,
				this.originalWeight
		);
		result.setType( this.getType() );
		result.setPriority( this.getPriority() );
		return result;
	}
}
